package com.greenline.pay.schedule.biz.task;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.greenline.pay.biz.dal.schedule.TaskLogDAO;
import com.greenline.pay.biz.dal.schedule.dataobject.TaskLogDO;

/**
 * 任务基类
 * 
 * @author weirui.shenwr
 * 
 */
public abstract class TaskBase {

    private final Log logger = LogFactory.getLog(getClass());

    @Resource
    private TaskLogDAO taskLogDAO;

    /**
     * 插入任务信息
     * 
     * @param taskInfo
     * @return
     */
    protected TaskLogDO insertTaskLog(TaskInfo taskInfo) {

        TaskLogDO taskLog = new TaskLogDO();
        taskLog.setStartTime(new Date());
        taskLog.setType(taskInfo.getTaskType());
        taskLog.setAmount(0L);
        taskLog.setRemark(taskInfo.getMessage());
        try {
            Long id = taskLogDAO.addTaskLog(taskLog);
            taskLog.setId(id);
        } catch (Exception ex) {
            logger.error("记录任务日志(开始)出错", ex);
        }
        return taskLog;
    }

    /**
     * 更新执行情况到DB
     * 
     * @param taskLog
     * @return
     */
    protected TaskLogDO updateTaskLog(TaskLogDO taskLog) {
        Date start = taskLog.getStartTime();
        Date end = new Date();
        Long duration = end.getTime() - start.getTime();
        taskLog.setEndTime(end);
        taskLog.setDuration(duration);
        try {
            taskLogDAO.updateTaskLog(taskLog);
        } catch (Exception ex) {
            logger.error("记录任务日志(完成)出错", ex);
        }
        return taskLog;
    }

    /**
     * 运行任务，并记录运行记录到DB
     * 
     * @param taskCallBack 具体任务
     */
    protected void excuteTask(TaskCallBack taskCallBack) {
        // 获取任务信息
        TaskInfo taskInfo = taskCallBack.initTaskInfo();
        if (taskInfo == null) {
            throw new IllegalArgumentException(taskCallBack.getClass() + " taskinfo is null.");
        }
        // 任务开始
        logger.info(taskInfo.getTaskType() + " start....");
        // 记录到DB
        TaskLogDO taskLog = new TaskLogDO();
        taskLog = insertTaskLog(taskInfo);
        try {
            // 执行任务
            taskInfo = taskCallBack.excute(taskInfo);
            taskLog.setBizKey(taskInfo.getBizKey());
            taskLog.setBizResult(taskInfo.getBizResult());
            taskLog.setRemark(taskInfo.getMessage());
            if (taskInfo.isSeccusss()) {
                // 设置任务
                taskLog.setAmount(Long.valueOf(taskInfo.getCount()));
                taskLog.setResult("成功");
            } else {
                taskLog.setResult("失败");
            }
        } catch (Exception ex) {
            logger.error(taskInfo.getTaskType() + "出错", ex);
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            String errorStack = "";
            try {
                ex.printStackTrace(pw);
                errorStack = sw.toString();
            } finally {
                pw.close();
            }
            if (errorStack.length() > 1300) {
                errorStack = errorStack.substring(0, 1300);
            }
            taskLog.setRemark("过程中出错:" + errorStack);
            taskLog.setResult("出错");
        } finally {
            updateTaskLog(taskLog);
        }
        logger.info(taskInfo.getTaskType() + "end!");
    }
}
